package com.bizfx.component.fields
{
	import flash.events.Event;
	
	import com.bizfx.component.controls.validators.ComboBoxValidator;
	import com.bizfx.component.views.IDetailView;
	import com.bizfx.utils.ObjectUtils;
	import com.bizfx.utils.StringUtils;
	
	import mx.collections.IList;
	import mx.containers.Box;
	import mx.controls.ComboBox;
	import mx.events.FlexEvent;
	import mx.events.ListEvent;
	import mx.events.ValidationResultEvent;
	import mx.utils.ObjectProxy;
	import mx.utils.UIDUtil;
	
	[Event(name="change", type="mx.events.ListEvent")]
	
	[Event(name="dataProviderChange", type="mx.events.FlexEvent")]
	
	public class ComboBoxField extends ComboBox implements IField, IInitableField, IValidationField
	{		
		private var _validator:ComboBoxValidator;
		
		public function ComboBoxField() {
			super();
			this.minWidth = 160;
			this._validator = new ComboBoxValidator();
			this._validator.prompt = "";
			this._validator.required = false;
			this._validator.requiredFieldError = "必选";
			this.setStyle("backgroundDisabledColor", 0xFFFFFF);
			this.setStyle("disabledOverlayAlpha", 0);
			this.setStyle("disabledColor", 0x000000);
			this.addEventListener(Event.CHANGE, fieldChangeHandler);
		}

		private function fieldChangeHandler(event:ListEvent):void {
			if (this.valueAsData && !StringUtils.isNullOrEmpty(this.valueField)) {
				if (this.selectedItem.hasOwnProperty(this.valueField)) {
					this._data = this.selectedItem[this.valueField];
				}
			} else {
				if (!this.editable) {
					this._data = this.selectedItem;
				} else {
					this._data = this.text;
				}
			}
		}
		
		public function get fieldKey():String {
			return this.id;
		}
		
		public function set fieldKey(value:String):void {
			id = value;
		}
		
		private var _data:Object;
		
		[Bindable("dataChange")]
		[Inspectable(environment="none")]
		override public function get data():Object
		{
			return _data;
		}
		
		override public function set data(value:Object):void {
			if (this.dataProvider != null) {
				var v:Object = "";
				
				if (value != null && this.valueAsData) {
					v = value;
				} else if (value != null && value.hasOwnProperty(this.valueField)) {
					v = value[this.valueField];
				}
				
				if (this.editable) {
					this.text = v.toString();
					this.selectedItem = v;
				} else {
					if (!StringUtils.isNullOrEmpty(this.valueField)) {
						if (this.dataProvider is IList) {
							for each(var d:Object in (this.dataProvider as IList)) {
								if (d && d.hasOwnProperty(this.valueField)) {
									if (d[this.valueField] == v) {
										this.selectedItem = d;
										break;
									}
								} else {
									this.selectedItem = v;
								}
							}
						}
					} else {
						this.selectedItem = v;
					}	
				}
			}
			_data = value;
			dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
		}
		
		private var _bindProperty:String;
		
		/**
		 * 需要绑定的fieldData属性。
		 */
		public function get bindProperty():String {
			return _bindProperty;
		}
		
		public function set bindProperty(value:String):void {
			_bindProperty = value;
		}
		
		[Bindable("dataProviderChange")]
		override public function set dataProvider(value:Object):void {
			if (value is IList) {
				if ((value as IList).length > 0) {
					var o:Object = (value as IList).getItemAt(0);
					if (o.hasOwnProperty(this.labelField)) {
						if (!StringUtils.isNullOrEmpty(o[this.labelField])) {
							var empty:Object = new Object();
							empty[this.labelField] = "";
							empty[this.valueField] = "";
							(value as IList).addItemAt(empty, 0);			
						}
					} else if (o is String) {
						if (!StringUtils.isNullOrEmpty(o.toString()))
							(value as IList).addItemAt("", 0);	
					}
				}
			}
			super.dataProvider = value;
			if (super.dropdown != null) {
				super.dropdown.dataProvider = value;
			}
			this.data = this._data;
			dispatchEvent(new FlexEvent("dataProviderChange"));
		}
		
		private var _initDataBindProperty:String;
		[Bindable]
		public function get initDataBindProperty():String
		{
			return _initDataBindProperty;
		}
		
		public function set initDataBindProperty(value:String):void {
			_initDataBindProperty = value;
		}
		
		public function validate():void {
			this._validator.source = this;
			this._validator.property = "selectedLabel";
			var event:ValidationResultEvent = this._validator.validate(this.selectedLabel);
			if (event.type != "valid") {
				this.errorString = "必选";
				this.setStyle("errorColor", "red");
			} else {
				this.errorString = "";
				this.setStyle("errorColor", "black");
			}
			this.dispatchEvent(event);
		}
		
		private var _valueField:String;
		[Bindable]
		public function get valueField():String
		{
			return _valueField;
		}
		
		public function set valueField(value:String):void {
			_valueField = value;
		}

		[Bindable]
		public function get required():Boolean
		{
			return this._validator.required;
		}
		
		public function set required(value:Boolean):void {
			this._validator.required = value;
		}
		
		private var _needInit:Boolean = false;
		[Bindable]
		public function get needInit():Boolean
		{
			return _needInit;
		}
		
		public function set needInit(value:Boolean):void {
			_needInit = value;
		}
		
//		private var _view:IDetailView;
//		
//		public function get view():IDetailView
//		{
//			return this._view;
//		}
//		
//		public function set view(value:IDetailView):void {
//			if (StringUtils.isNullOrEmpty(this.id)) {
//				this.id = UIDUtil.createUID();
//			}
//			if (this._view !== value) {
//				if (_view) {
//					_view.removeFieldByKey(this.fieldKey);
//				}
//				this._view = value;
//				if (_view) {
//					_view.addField(this);
//				}
//			}
//		}
		
		private var _valueAsData:Boolean = true;
		[Bindable]
		public function get valueAsData():Boolean{
			return this._valueAsData;
		}
		
		public function set valueAsData(value:Boolean):void {
			this._valueAsData = value;
		}
	
		[Inspectable(category="General", enumeration="true,false", defaultValue="false")]
		[Bindable("readOnlyChanged")]
		public function get readOnly():Boolean {
			return this.enabled;
		}
		
		public function set readOnly(value:Boolean):void {
			if (this.enabled == value) {
				this.enabled = !value;
				this.dispatchEvent(new Event("readOnlyChanged"));
			}
		}
	}
}